import BaseUtil from '@/BaseUtil';
import BuffUtil from '@/BuffUtil';
import ObjectPool from '@/ObjectPool';
import UnitDeathEvent from '@/event/UnitDeathEvent';
import { OrderId } from '@/globals/order';

export default class StunSystem {
    private tiemrPool: Map<unit, number> = new Map();
    private stunBuffId = FourCC('Bpua');
    buffId = 'buff_stun';
    buffType: AppBuffType = {
        id: 'buff_stun',
        name: '眩晕',
        art: 'ReplaceableTextures\\CommandButtons\\BTNStun.blp',
        ubertip: '该单位被眩晕了',
        dur: 10,
        targetAttach: 'overhead',
        targetArt: 'Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl',
    };
    private pool: ObjectPool<unit> = new ObjectPool(this.poolCreator);
    private poolCreator() {
        return CreateUnit(Player(0), 'ethu', 0, 0, 0);
    }
    unEffectBuffId = 'buff_stun_un_effect';
    unEffectBuffType: AppBuffType = {
        id: 'buff_stun_un_effect',
        name: '免疫眩晕',
        class: '隐藏',
        art: '',
        ubertip: '单位免疫眩晕',
    };

    buffColdId = 'buff_colded';
    buffColdType: AppBuffType = {
        id: 'buff_colded',
        name: '冰冻',
        art: 'ReplaceableTextures\\CommandButtons\\BTNFrost.blp',
        ubertip: '该单位被冰冻了',
        dur: 99,
        targetArt: 'Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl',
        targetAttach: 'origin',
    };
    constructor() {
        BuffUtil.registerBuffType(this.buffType);
        BuffUtil.registerBuffType(this.buffColdType);
        BuffUtil.registerBuffType(this.unEffectBuffType);
        se.onUnitDeath(StunSystem.处理死亡);
        BaseUtil.onTimer(0.04, this.眩晕计时);
    }
    眩晕计时() {
        for (let [unit, time] of StunSystemIntance.tiemrPool) {
            if (time <= 0) {
                StunSystemIntance.取消眩晕(unit);
                continue;
            }
            StunSystemIntance.tiemrPool.set(unit, time - 0.04);
            if (BuffUtil.hasUnitBuff(unit, StunSystemIntance.unEffectBuffId)) {
                StunSystemIntance.取消眩晕(unit);
            }
        }
        return true;
    }
    static 处理死亡(this: void, d: UnitDeathEvent) {
        StunSystemIntance.取消眩晕(GetTriggerUnit());
    }
    取消眩晕(unit: unit) {
        if (BuffUtil.hasUnitBuff(unit, StunSystemIntance.buffId)) {
            BuffUtil.clearUnitBuff(unit, StunSystemIntance.buffId);
        }
        UnitRemoveBuffBJ(StunSystemIntance.stunBuffId, unit);
        if (!StunSystemIntance.tiemrPool.has(unit)) return;
        StunSystemIntance.tiemrPool.delete(unit);
    }
    private getAnVest(t: unit, o?: unit) {
        let v = StunSystemIntance.pool.borrowObject();
        SetUnitX(v, GetUnitX(t));
        SetUnitY(v, GetUnitY(t));
        if (o) SetUnitOwner(v, GetOwningPlayer(o), false);
        SetUnitLifePercentBJ(v, 100);
        SetUnitManaPercentBJ(v, 100);
        return v;
    }
    stun(目标: unit, 时长: number, 来源: unit = null, type: '冰冻' | '眩晕' = '眩晕') {
        if (!IsUnitAliveBJ(目标)) return;
        if (BuffUtil.hasUnitBuff(目标, StunSystemIntance.unEffectBuffId)) return;
        let buffId = type == '冰冻' ? StunSystemIntance.buffColdId : StunSystemIntance.buffId;
        if (!StunSystemIntance.tiemrPool.has(目标)) {
            let v = StunSystemIntance.getAnVest(目标, 来源);
            IssueTargetOrderById(v, OrderId.Thunderbolt, 目标);
            StunSystemIntance.tiemrPool.set(目标, 时长);
            BuffUtil.addBuff(目标, buffId, 来源, (buff) => {
                buff.durMS = Math.floor(时长 * 1000);
            });
            BaseUtil.runLater(1, () => {
                StunSystemIntance.pool.returnObject(v);
            });
        } else {
            let old = StunSystemIntance.tiemrPool.get(目标);
            if (old < 时长) {
                StunSystemIntance.tiemrPool.set(目标, 时长);
                BuffUtil.addBuff(目标, buffId, 来源, (buff) => {
                    buff.durMS = Math.floor(时长 * 1000);
                });
            }
        }
    }
    群体眩晕(目标: unit[], 时长: number, 来源: unit = null) {
        for (let u of 目标) {
            StunSystemIntance.stun(u, 时长, 来源);
        }
    }
}
